package yo;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class MainActivity extends MapActivity {

	/**
	 * mapController is properties
	 * */
	private MapController mapController;

	/**
	 * mapView is properties
	 * */
	private MapView mapView;

	/**
	 * locationManager is properties
	 * */
	private LocationManager locationManager;

	/**
	 * location is properties
	 * */
	private Location location;

	/**
	 * counter is properties
	 * */
	private Timer counter;

	/**
	 * locationListener is properties
	 * */
	LocationUpdateHandler locationListener;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		init();
		setContentView(mapView);

		// Get a handle on the location manager
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		
		// Initialize locationListener variable.
		locationListener = new LocationUpdateHandler();

		// Get last location.
		location = locationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
				1000, 1, locationListener);
		
		// Send to server.
		if (location != null) {
			double lat = location.getLatitude();
			double lng = location.getLongitude();
			sendPositionToServer(lat, lng);
		}
		
		// Initialize counter variable.
		counter = new Timer();
		counter.schedule(new TimerTask() {

			@Override
			public void run() {
				sendToServer();
			}
		}, 0, 5000);
	}

	/**
	 * LocationUpdateHandler is class implement from LocationListener class
	 * */
	public class LocationUpdateHandler implements LocationListener {

		/**
		 * Event location changed
		 * */
		@Override
		public void onLocationChanged(Location loc) {
			location = loc;
		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * init() used to initialize mapView variable.
	 * */
	private void init() {

		// Initialize mapView variable with key
		// "0M1WMfh-qlemQ5wkYiHiSMy1fD_-8ed122mb70w"
		mapView = new MapView(this, "0M1WMfh-qlemQ5wkYiHiSMy1fD_-8ed122mb70w");
		// Initialize mapController variable.
		mapController = mapView.getController();

		// Set size zoom
		mapController.setZoom(15);

		// Set horizon scroll bar
		mapView.setHorizontalScrollBarEnabled(true);
		mapView.setScrollContainer(true);
		mapView.setBuiltInZoomControls(true);

		// Create and set point with coordinates latitude :10775639, longitude
		// :106700420
		GeoPoint point = new GeoPoint(10775639, 106700420);
		mapController.setCenter(point);

		mapView.displayZoomControls(true);
		mapView.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
			}
		});

		// Set properties to mapView.
		mapView.setTraffic(true);
		mapView.setSoundEffectsEnabled(true);
		mapView.setAddStatesFromChildren(true);
		mapView.setClickable(true);
	}

	/**
	 * getClient() used to get DefaultHttpClient
	 * 
	 * @return a DefualtHttpClient was set up parameters support both http and
	 *         https
	 * */
	public DefaultHttpClient getClient() {
		DefaultHttpClient ret = null;

		// Sets up parameters
		HttpParams params = new BasicHttpParams();
		HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
		HttpProtocolParams.setContentCharset(params, "utf-8");
		params.setBooleanParameter("http.protocol.expect-continue", false);

		// Registers schemes for both http and https
		SchemeRegistry registry = new SchemeRegistry();
		registry.register(new Scheme("http", PlainSocketFactory
				.getSocketFactory(), 80));
		final SSLSocketFactory sslSocketFactory = SSLSocketFactory
				.getSocketFactory();
		sslSocketFactory
				.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
		registry.register(new Scheme("https", sslSocketFactory, 443));

		ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(
				params, registry);
		ret = new DefaultHttpClient(manager, params);
		return ret;
	}

	/**
	 * sendPositionToServer used to send coordinates to web server.
	 * 
	 * @param latitude
	 *            the latitude is current latitude of equipment.
	 * @param longitude
	 *            the longitude is current longitude of equipment.
	 * */
	private void sendPositionToServer(double latitude, double longitude) {
		try {
			// Get http client.
			HttpClient client = getClient();

			// Create method get httpget.
			HttpGet get = new HttpGet(
					"http://bpt2410.myvnc.com/TTHDHM_TimVetDuongDi/PositionServlet?action=sendPosition&serial=123456&latitude="
							+ latitude + "&longitude=" + longitude);

			// Request to the server
			HttpResponse response = client.execute(get);

			// Get response status.
			StatusLine status = response.getStatusLine();
			if (status.getStatusCode() == HttpStatus.SC_OK) {
				String text = "";
				// Show result if connection successfully!
				Toast.makeText(getApplicationContext(), "Ket noi thanh cong",
						Toast.LENGTH_SHORT).show();
				GeoPoint point = new GeoPoint((int) (latitude * 1E6),
						(int) (longitude * 1E6));

				// Set again mapController variable.
				mapController.setCenter(point);

				// Set and show current coordinates.
				text = "Vi Tri: " + latitude + ":" + longitude;
				Toast.makeText(getApplicationContext(), text,
						Toast.LENGTH_SHORT).show();
				Geocoder gc = new Geocoder(this, Locale.getDefault());

				try {

					// Get list address have coordinates.
					List<Address> addresses = gc.getFromLocation(latitude,
							longitude, 1);

					StringBuilder sb = new StringBuilder();

					// Get first address.
					if (addresses.size() > 0) {
						Address address = addresses.get(0);

						for (int i = 0; i < address.getMaxAddressLineIndex(); i++)
							sb.append(address.getAddressLine(i)).append("\n");
						sb.append(address.getCountryName());
					}

					// Show address.
					text = sb.toString();
					Toast.makeText(getApplicationContext(), text,
							Toast.LENGTH_LONG).show();
				} catch (IOException e) {

					// Show error.
					Toast.makeText(getApplicationContext(), "Loi",
							Toast.LENGTH_LONG).show();
				}

				// Set again mapView.
				setContentView(mapView);
			} else {

				// Show error if connection fail.
				Toast.makeText(getApplicationContext(),
						"Ket noi ko thanh cong", Toast.LENGTH_SHORT).show();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

			// Show error.
			Toast.makeText(getApplicationContext(), e.getMessage(),
					Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * sendToServer used send coordinates by timer
	 * */
	private void sendToServer() {
		this.runOnUiThread(Timer_Tick);
	}

	/**
	 * Thread Timer_Tick used send coordinates to server by timer.
	 * */
	private Runnable Timer_Tick = new Runnable() {
		public void run() {
			if (location != null) {
				double lat = location.getLatitude();
				double lng = location.getLongitude();
				sendPositionToServer(lat, lng);
			}
		}
	};

}